package com.dzl.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dzl.api.pojo.Order;
import com.dzl.api.pojo.WelfareBlueBrothersOrder;
import com.dzl.api.service.BlueBrothersService;
import com.dzl.api.service.WelfareBlueBrothersOrderService;
import com.dzl.api.util.OkHttpUtil;
import com.dzl.config.database.Master;
import com.dzl.config.exception.CommonException;
import com.dzl.constant.ApiFuLuConstant;
import com.dzl.constant.ApiBlueBrothersConstant;
import com.dzl.fulu.sup.open.api.core.utils.JSONUtil;
import com.dzl.fulu.sup.open.api.model.InputDirectOrderDto;
import com.dzl.fulu.sup.open.api.model.InputOrderGetDto;
import com.dzl.fulu.sup.open.api.model.InputProductDto;
import com.dzl.fulu.sup.open.api.model.response.DefaultClientResponse;
import com.dzl.fulu.sup.open.api.sdk.DefaultOpenApiClient;
import com.dzl.operation.service.OperationLogService;
import com.dzl.order.pojo.WelfareOrder;
import com.dzl.order.pojo.WelfareOrderExp;
import com.dzl.order.service.WelfareOrderExpService;
import com.dzl.order.service.WelfareOrderService;
import com.dzl.util.EmptyUtils;
import com.dzl.util.MD5Util;
import com.dzl.util.RedisUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.regex.Pattern;

/**
 * 蓝色兄弟充值
 *
 * @author WangJian
 * @date 2021/7/13 0013
 */
@Slf4j
@Service
public class BlueBrothersServiceImpl implements BlueBrothersService {
    @Autowired
    private WelfareOrderExpService welfareOrderExpService;
    @Autowired
    private OperationLogService operationLogService;
    @Autowired
    private WelfareBlueBrothersOrderService welfareBlueBrothersOrderService;
    @Autowired
    private WelfareOrderService welfareOrderService;

    public static String generateSignature(final Map<String, String> data, String key) {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (data.get(k).trim().length() > 0) {
                // 参数值为空，则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
            }
        }
        sb.append("key=").append(key);
        String sign = MD5Util.getMd5(sb.toString());
        return sign.toUpperCase();
    }

    @Override
    public String chargingForBlueBrotherOrFuLu(Order order) {
        log.info("directCharging in");
        // 更新该订单状态为充值中
        Example welfareOrderExpExample = new Example(WelfareOrderExp.class);
        welfareOrderExpExample.createCriteria().andEqualTo("orderId", order.getOrderId());
        WelfareOrderExp welfareOrderExpUpd = new WelfareOrderExp();
        welfareOrderExpUpd.setStatus(2);
        welfareOrderExpUpd.setAccountType(order.getAccountType());
        welfareOrderExpUpd.setUpdateTime(new Date());
        welfareOrderExpService.updateByExampleSelective(welfareOrderExpUpd, welfareOrderExpExample);
        String s = "";
        if (order.getMerchantId().equals(ApiBlueBrothersConstant.MERCHANT_ID)) {
            //手机号规则
            String PhonePattern = "^1[3456789]\\d{9}$";
            //QQ号规则
            String QQPattern = "(^[1-3]{1}\\d{4,9}$)|(^[1-9]{1}\\d{4,8}$)";
            if (Pattern.compile(PhonePattern).matcher(order.getRechargeAccount()).matches()) {
                order.setAccountType(1);
            } else if (Pattern.compile(QQPattern).matcher(order.getRechargeAccount()).matches()) {
                order.setAccountType(2);
            } else {
                order.setAccountType(0);
            }
            long l = System.currentTimeMillis() / 1000;
            Map<String, String> map = new HashMap<>();
            //账号类型(1:手机号 2:QQ号 其他：0)
            map.put("accountType", String.valueOf(order.getAccountType()));
            map.put("merchantId", String.valueOf(order.getMerchantId()));
            //请求回调地址
            map.put("notifyUrl", ApiBlueBrothersConstant.NOTIFY_URL);
            map.put("number", "1");
            map.put("outTradeNo", order.getOutTradeNo());
            //101 测试失败请求  106 测试成功请求
            map.put("productId", String.valueOf(order.getProductId()));
            map.put("rechargeAccount", order.getRechargeAccount());
            map.put("timeStamp", String.valueOf(l));
            log.info("directCharging map: " + map);
            String s1 = generateSignature(map, ApiBlueBrothersConstant.KEY);
            log.info("directCharging s1: " + s1);
            String data = "merchantId=" + order.getMerchantId() + "&outTradeNo=" + order.getOutTradeNo() + "&timeStamp=" + l + "&rechargeAccount=" + order.getRechargeAccount() + "&accountType=" + order.getAccountType() + "&notifyUrl=" + ApiBlueBrothersConstant.NOTIFY_URL + "&sign=" + s1 + "&productId=" + order.getProductId() + "&number=1&version=1.0";
            log.info("directCharging data: " + data);
            //添加日志
            operationLogService.saveBlueCharging(order.getOrderId(), "blueBrother data:" + data);
            //下单请求
            s = OkHttpUtil.httpPost(ApiBlueBrothersConstant.DIRECT_URL, data);
            log.info("directCharging s: " + s);
        } else if (order.getMerchantId().equals(ApiFuLuConstant.APP_KEY)) {
            DefaultOpenApiClient client =
                    new DefaultOpenApiClient(ApiFuLuConstant.URL, ApiFuLuConstant.APP_KEY, ApiFuLuConstant.SYS_SECRET, ApiFuLuConstant.OPEN_API_DIRECT_ORDER_ADD);
            InputDirectOrderDto dto = new InputDirectOrderDto();
            dto.setProductId(order.getProductId());
            dto.setCustomerOrderNo(order.getOutTradeNo());
            dto.setChargeAccount(order.getRechargeAccount());
            dto.setBuyNum(1);
            log.info("directCharging map: " + dto);
            //添加日志
            operationLogService.saveBlueCharging(order.getOrderId(), "blueBrother data:" + dto);
            client.setBizObject(dto);
            s = client.excute();
            log.info("directCharging s1: " + s);
            if (!JSONObject.parseObject(s).getString("code").equals("0")) {
                throw new CommonException(JSONObject.parseObject(s).getString("message"));
            }
        } else {
            throw new CommonException("下单失败，请联系客服");
        }

        return s;
    }

    @Master
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WelfareBlueBrothersOrder queryOrder(Order order) {
        //redis
        String key = RedisUtil.ORDER_BLUE_BROTHERS_PREFIX + order.getOutTradeNo();
        //查数据库
        WelfareBlueBrothersOrder welfareBlueBrothersOrder = new WelfareBlueBrothersOrder();
        welfareBlueBrothersOrder.setOutTradeNo(order.getOutTradeNo());
        List<WelfareBlueBrothersOrder> brothersOrderList = welfareBlueBrothersOrderService.select(welfareBlueBrothersOrder);
        if (RedisUtil.get(key) != null && EmptyUtils.isNotEmpty(brothersOrderList)) {
            return brothersOrderList.get(0);
        }
        if (order.getMerchantId().equals(ApiBlueBrothersConstant.MERCHANT_ID)) {
            long l = System.currentTimeMillis() / 1000;
            Map<String, String> map = new HashMap<>();
            map.put("merchantId", String.valueOf(order.getMerchantId()));
            map.put("outTradeNo", order.getOutTradeNo());
            map.put("timeStamp", String.valueOf(l));
            String s1 = generateSignature(map, ApiBlueBrothersConstant.KEY);
            //查询订单
            String s = OkHttpUtil.httpPost(ApiBlueBrothersConstant.ORDER_URL, "merchantId=" + order.getMerchantId() + "&outTradeNo=" + order.getOutTradeNo() + "&timeStamp=" + l + "&sign=" + s1 + "&version=1.0");
            String code = JSONObject.parseObject(s).getString("code");
            if (!code.equals("0000")) {
                switch (code) {
                    case "1002":
                        log.info("签名错误！");
                        throw new CommonException("商户信息有误");
                    case "1003":
                        log.info("商户不存在！");
                        throw new CommonException("订单查询失败，请检查供应商信息是否正确");
                    case "1012":
                        log.info("无效订单！");
                        throw new CommonException("供应商订单无效！");
                    default:
                        log.info(s);
                        break;
                }
            }
            welfareBlueBrothersOrder = new Gson().fromJson(s, WelfareBlueBrothersOrder.class);
        } else if (order.getMerchantId().equals(ApiFuLuConstant.APP_KEY)) {
            DefaultOpenApiClient client =
                    new DefaultOpenApiClient(ApiFuLuConstant.URL, ApiFuLuConstant.APP_KEY, ApiFuLuConstant.SYS_SECRET, ApiFuLuConstant.OPEN_API_ORDER_GET);
            InputOrderGetDto dto = new InputOrderGetDto();
            dto.setCustomerOrderNo(order.getOutTradeNo());
            client.setBizObject(dto);
            String s = client.excute();
            if (!JSONObject.parseObject(s).getString("code").equals("0")) {
                throw new CommonException(JSONObject.parseObject(s).getString("message"));
            }
            DefaultClientResponse response = JSONUtil.fromJSON(s, new TypeToken<DefaultClientResponse>() {
            });
            String orderState = JSONObject.parseObject(response.getResult()).getString("order_state");
            String status = "02";
            Integer status1 = 2;
            if (orderState.equals("success")) {
                status = "01";
                status1 = 3;
            } else if (orderState.equals("processing")) {
                status = "02";
                status1 = 2;
            } else if (orderState.equals("failed")) {
                status = "03";
                status1 = 4;
            } else if (orderState.equals("untreated")) {
                status = "04";
                status1 = 2;
            }
            welfareBlueBrothersOrder.setStatus(status);
            welfareBlueBrothersOrder.setOutTradeNo(order.getOutTradeNo());
            welfareBlueBrothersOrder.setMessage(response.getMessage());

            WelfareOrder welfareOrder = new WelfareOrder();
            welfareOrder.setOrderNo(order.getOutTradeNo());
            List<WelfareOrder> select = welfareOrderService.select(welfareOrder);
            if (EmptyUtils.isNotEmpty(select)) {
                Integer id = select.get(0).getId();
                welfareOrderExpService.updateStatus(id, status1);
            }
        } else {
            throw new CommonException("下单失败，请联系客服");
        }

        // 设置查询间隔 5分钟只实时查询一次
        RedisUtil.set(key, "cache", 300);
        //写入数据库
        if (EmptyUtils.isEmpty(brothersOrderList)) {
            welfareBlueBrothersOrderService.insertSelective(welfareBlueBrothersOrder);
        } else {
            welfareBlueBrothersOrderService.updateByOrderNo(welfareBlueBrothersOrder);
        }
        return welfareBlueBrothersOrder;
    }

    @Override
    public String queryBalance(Order order) {
        long l = System.currentTimeMillis() / 1000;
        Map<String, String> map = new HashMap<>();
        map.put("merchantId", String.valueOf(order.getMerchantId()));
        map.put("timeStamp", String.valueOf(l));
        String s1 = generateSignature(map, ApiBlueBrothersConstant.KEY);
        //查询余额
        String s = OkHttpUtil.httpPost(ApiBlueBrothersConstant.BALANCE_URL, "merchantId=" + order.getMerchantId() + "&timeStamp=" + l + "&sign=" + s1 + "&version=1.0");
        if (!JSONObject.parseObject(s).getString("code").equals("0000")) {
            throw new CommonException("余额查询失败，请检查供应商信息是否正确");
        }
        return s;
    }

    @Override
    public String queryProduct(Order order) {
        String s = "";
        //蓝色兄弟
        if (order.getMerchantId().equals(ApiBlueBrothersConstant.MERCHANT_ID)) {
            long l = System.currentTimeMillis() / 1000;
            Map<String, String> map = new HashMap<>();
            map.put("merchantId", String.valueOf(order.getMerchantId()));
            map.put("timeStamp", String.valueOf(l));
            String s1 = generateSignature(map, ApiBlueBrothersConstant.KEY);
            //查询产品
            s = OkHttpUtil.httpPost(ApiBlueBrothersConstant.PRODUCT_URL, "merchantId=" + order.getMerchantId() + "&timeStamp=" + l + "&sign=" + s1 + "&version=1.0");
            if (!JSONObject.parseObject(s).getString("code").equals("0000")) {
                throw new CommonException("产品查询失败，请检查供应商信息是否正确");
            }
            //福禄
        } else if (order.getMerchantId().equals(ApiFuLuConstant.APP_KEY)) {
            DefaultOpenApiClient client =
                    new DefaultOpenApiClient(ApiFuLuConstant.URL, ApiFuLuConstant.APP_KEY, ApiFuLuConstant.SYS_SECRET, ApiFuLuConstant.OPEN_API_GOODS_LIST_GET);
            InputProductDto dto = new InputProductDto();
            client.setBizObject(dto);
            s = client.excute();
            if (!JSONObject.parseObject(s).getString("code").equals("0")) {
                throw new CommonException(JSONObject.parseObject(s).getString("message"));
            }
        } else {
            throw new CommonException("产品查询失败，请检查供应商信息是否正确");
        }
        return s;
    }
}
